#include<iostream>
#include<vector>
#include<string>
#include<chrono>
#include<unordered_map>
#include<sw/redis++/redis++.h>
#include<thread>
#include"Util.hpp"
using namespace std;
using namespace std::chrono_literals;
using namespace sw::redis;

void test1(sw::redis::Redis& redis)
{
    cout << "set和get"<< endl;
    redis.flushall();

    redis.set("key1","111");
    auto val1 = redis.get("key1");
    if(val1)
    cout << "value1:" << val1.value() << endl;

    redis.set("key2","222");
    auto val2 = redis.get("key2");
    if(val2)
    cout << "value2:" << val2.value() << endl;
}

void test2(sw::redis::Redis& redis)
{
     cout << "set超时时间"<< endl;
    redis.flushall();

    redis.set("key1","111",std::chrono::seconds(10));
    auto val1 = redis.get("key1");
    //获取过期时间
    std::this_thread::sleep_for(std::chrono::seconds(3));
    auto ttl = redis.ttl("key1");
    cout << ttl << endl;
}

void test3(sw::redis::Redis& redis)
{
    cout << "set使用NX XX"<< endl;
    redis.flushall();
    redis.set("key1","111");
    // redis.set("key1","222",0s,sw::redis::UpdateType::NOT_EXIST);
    redis.set("key1","222",0s,sw::redis::UpdateType::EXIST);
    auto val1 = redis.get("key1"); //已经存在
    if(val1)  cout <<  "val1: " << val1.value() << endl;
    else cout << "key不存在"<<endl;
}

void test4(sw::redis::Redis& redis)
{
    cout << "mset使用" << endl;
    redis.flushall();
    //写法1
    // redis.mset({std::make_pair("k1","111"),std::make_pair("k2","222"),std::make_pair("k3","333")});

    //写法2:提前存储到容器
    unordered_map<string,string> ump = {{"k1","111"},{"k2","222"},{"k3","333"}};
    redis.mset(ump.begin(),ump.end());
    auto val1  = redis.get("k1");
    if(val1) cout << val1.value() << endl;
    auto val2  = redis.get("k2");
    if(val2) cout << val2.value() << endl; 
    auto val3  = redis.get("k3");
    if(val3) cout << val3.value() << endl;
}

void test5(sw::redis::Redis& redis)
{
    cout << "mget使用" << endl;
    redis.flushall();
    //先设置元素
    unordered_map<string,string> ump = {{"k1","111"},{"k2","222"},{"k3","333"}};
    redis.mset(ump.begin(),ump.end());

    vector<sw::redis::OptionalString> result; //注意指明OptionalString类型的命名空间
    //写法一:初始化列表
    // redis.mget({"k1","k2","k3","k4"},std::back_inserter(result));

    //写法2：提前存储到容器
    vector<string> keys = {"k1","k2","k3","k4"};
    redis.mget(keys.begin(),keys.end(),std::back_inserter(result));
    printContainerOptional(result);
}

void test6(sw::redis::Redis& redis)
{
   cout << "getrange和setrange使用" << endl;
   redis.flushall();

   redis.set("key","abcdefghijk");
   string ret = redis.getrange("key",0,-1);
   cout << "ret:" << ret << endl;

   redis.setrange("key",2,"xyz");
   auto val = redis.get("key");
   if(val) cout << val.value() << endl;
}

void test7(sw::redis::Redis& redis)
{
   cout << "incr和decr使用" << endl;
   redis.flushall();

   //incr 
   redis.set("key","100");
   auto ret = redis.incr("key");
   cout << "after incr: " << ret << endl;
   auto val = redis.get("key");
   if(val) cout << "key value: " << val.value() << endl;

   auto ret1 = redis.decr("key");
   cout << "after decr: " << ret1 << endl;
    val = redis.get("key");
   if(val) cout << "key value: " << val.value() << endl;
}


int main()
{
   sw::redis::Redis redis("tcp://127.0.0.1:6379");
   test7(redis);
    return 0;
}